package cn.com.wxd.service.zookeeper.registry;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;

import cn.com.wxd.common.GlobalConstant;
import cn.com.wxd.common.JsonUtil;
import cn.com.wxd.service.zookeeper.ZkData;

/**
 * Title:
 * Description:
 * <p>
 * Company: Amumu系统
 * Copyright: Copyright (c) 2017
 * All right reserved.
 * Created by WangXuDong on 2017/8/22.
 *
 * @author WangXuDong
 * @version 1.0
 */
public class ZookeeperRegistService {
    private static final String ROOTNODE = GlobalConstant.ZOOKEEPERROOTNODE;

    /**
     * 注册一个约定好的服务
     *
     * @param zk         当前zookeeper实例
     * @param serverName 服务名称
     * @param zkData     zkData
     *
     * @return 返回服务路径
     *
     * @throws Exception 注册服务出现错误
     */
    public static String register(ZooKeeper zk, String serverName, ZkData zkData) throws
            Exception {
        if (zk == null) {
            throw new Exception("ZooKeeper zk不能为null，无法注册服务!");
        }

        /**
         * 四种形式的目录节点，分别是
         * PERSISTENT：持久化目录节点，这个目录节点存储的数据不会丢失；
         * PERSISTENT_SEQUENTIAL：顺序自动编号的目录节点，这种目录节点会根据当前已近存在的节点数自动加1,
         * 然后返回给客户端已经成功创建的目录节点名；
         * EPHEMERAL：临时目录节点，一旦创建这个节点的客户端与服务器端口也就是超时，这种节点会被自动删除；
         * EPHEMERAL_SEQUENTIAL：临时自动编号节点
         */
        //创建跟节点
        if (zk.exists(ROOTNODE, false) == null) {
            zk.create(ROOTNODE, "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        }

        //创建服务节点
        if (zk.exists(ROOTNODE + "/server", false) == null) {
            zk.create(ROOTNODE + "/server", "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        }
        //创建服务节点
        if (zk.exists(ROOTNODE + "/server/" + serverName, false) == null) {
            zk.create(ROOTNODE + "/server/" + serverName, "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
                    CreateMode.PERSISTENT);
        }

        //注册服务,并返回注册好的地址
         return zk.create(ROOTNODE + "/server/" + serverName + "/{" + zkData.getIp() + ":" + zkData.getPort() + "}-",
                    JsonUtil.objectToJson(zkData).getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
                    CreateMode.EPHEMERAL_SEQUENTIAL);

    }
}
